package com.youle.robots.gateway.config;


import com.alibaba.fastjson.JSON;
import com.youle.robots.MapKeyComparator;
import com.youle.robots.gateway.api.InterceptorExcption;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.MessageDigest;
import java.util.*;

/**
 * 签名校验
 */
@Slf4j
@Component
public class SignInterceptor implements HandlerInterceptor {

    private final String SIGN = "sign";

    @Value("${secretkey}")
    private String SECRETKEY;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
            Exception {

        String sign = request.getHeader(SIGN);
        if (StringUtils.isEmpty(sign)) {
            // 没有签名的非法请求，直接拒绝
            throw new InterceptorExcption("[sign] must be not empty!", HttpStatus.BAD_REQUEST);
        }

        /*
         * 计算sign
         */
        Map<String, Object> param = new HashMap<>();
        // 获取所有参数
        Enumeration keys = request.getParameterNames();
        String key;
        while (keys.hasMoreElements()) {
            key = (String) keys.nextElement();
            param.put(key, request.getParameter(key));
        }

        // 参数排序
        if (param.size() == 0) {
            // 无参的非法请求，直接拒绝
            throw new InterceptorExcption("非法请求", HttpStatus.BAD_REQUEST);
        }

        // 打印请求参数
        log.debug(JSON.toJSONString(param));

        Map<String, Object> sortMap = new TreeMap<String, Object>(new MapKeyComparator());
        sortMap.putAll(param);//排序完成

        // 头尾添加私钥计算签名
        StringBuilder builder = new StringBuilder(SECRETKEY);
        for (Map.Entry<String, Object> entry : sortMap.entrySet()) {
            builder.append(entry.getKey());
            builder.append(entry.getValue());
        }
        builder.append(SECRETKEY);

        MessageDigest md5 = MessageDigest.getInstance("MD5");
        BASE64Encoder base64Encoder = new BASE64Encoder();
        // md5摘要值
        String serverSign = base64Encoder.encode(md5.digest(builder.toString().getBytes("utf-8")));

        log.debug("服务端签名值为：sign=" + serverSign);

        Boolean flag = Objects.equals(sign, serverSign);

        if (!flag) {
            // 返回 错误信息
            throw new InterceptorExcption("签名无效", HttpStatus.BAD_REQUEST);
        }

        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView
            modelAndView) {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception
            ex) {
    }
}
